home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Nebula 2
/
Nebula Two.iso
/
SourceCode
/
Tutorial
/
Cookbook
/
41.PieChart
/
PieChartView.m
< prev
next >
Wrap
Text File
|
1995-06-12
|
24KB
|
268 lines
#import "PieChartView.h"
#import <strings.h>
#import <appkit/Font.h>
#import "slice.h"
#import <appkit/Control.h>
#import <appkit/Application.h>
#import <appkit/Pasteboard.h>
#import <appkit/Matrix.h>
#import <dpsclient/wraps.h>
@implementation PieChartView:View
+newFrame:(const NXRect *)tF
{
int i;
// we are using the Appkit "newFrame" plus our own additions
self = [super newFrame:tF];
fontID = [Font newFont:"Helvetica"
size:14.0
style:0
matrix:NX_IDENTITYMATRIX];
numWedges = 3;
wedgeValue[0] = 100.0; strcpy(labels[0], "Apples"); grays[0] = 1.0;
wedgeValue[1] = 200.0; strcpy(labels[1], "Bananas"); grays[1] = 0.333;
wedgeValue[2] = 300.0; strcpy(labels[2], "Oranges"); grays[2] = 0.666;
pieSize = 100.0;
pieFontSize = 14.0;
for (i=3; i<10; i++) {
grays[i] = ((float) i)/10.0;
}
[self normalize];
return self;
}
// --------------- methods that respond to user actions start here --------------
- takeValueFromMatrix:sender
{
int i;
i = [sender selectedRow];
if (i >= numWedges) {
numWedges = i+1;
[numWedgesText setIntValue:numWedges];
}
wedgeValue[i] = [sender floatValue];
[self normalize];
[self display];
return self;
}
- takeLabelFromMatrix:sender
{
int i;
i = [sender selectedRow];
if (i >= numWedges) {
numWedges = i+1;
[numWedgesText setIntValue:numWedges];
}
strcpy(labels[i],[sender stringValue]);
[self display];
return self;
}
- takeGraysFromMatrix:sender
{
int i;
i = [sender selectedRow];
grays[i] = [sender floatValue];
[self display];
return self;
}
- takePieSizeFrom:sender
{
float tmpFlt;
tmpFlt = [sender floatValue];
[pieSizeText setIntValue:tmpFlt];
[self setPieSize:tmpFlt];
return self;
}
-takeFontSizeFrom:sender
{
float tmpFlt;
tmpFlt = [sender floatValue];
[labelLineLengthText setIntValue:tmpFlt];
[self setPieFontSize:tmpFlt];
return self;
}
-takeNumWedgesFrom:sender
{
numWedges = [sender intValue];
[numWedgesText setIntValue:numWedges];
[self normalize];
return self;
}
- copy:sender
{
id pb = [NXApp pasteboard]; /* global Pasteboard object */
NXStream *st; /* stream to collect data in */
char *data; /* actual data buffer */
int length; /* length of data */
int maxLength; /* (not used here) */
// To see how to use the pasteboard see page 10-33 of
// the SysRefMan
// declare that we will supply a single type of data: PostScript
[pb declareTypes:&NXPostScriptPboard num:1 owner:self];
/* get a stream which writes to memory */
st = NXOpenMemory( NULL, 0, NX_WRITEONLY );
/* write PostScript code for this view into the stream */
[self copyPSCodeInside:NULL to:st];
/* get actual data buffer from stream */
NXGetMemoryBuffer( st, &data, &length, &maxLength );
/* write PostScript data to pasteboard */
[pb writeType:NXPostScriptPboard data:data length:length];
/* deallocate stream, including its buffer */
NXCloseMemory( st, NX_FREEBUFFER );
return self;
}
/* make this view accept first responder so it will understand copy */
-(BOOL)acceptsFirstResponder
{
return (YES);
}
-resignFirstResponder
{
return self;
}
// --------------- end of action methods --------------
// --------------- start of outlets --------------
- setNumWedgesText:anObject
{
numWedgesText = anObject;
return self;
}
- setPieSizeText:anObject
{
pieSizeText = anObject;
return self;
}
- setLabelLineLengthText:anObject
{
labelLineLengthText = anObject;
return self;
}
- setPieFontText:anObject
{
pieFontText = anObject;
return self;
}
// --------------- end of outlets -------------- ~
-setPieSize: (float) size
{
pieSize = size;
[self display];
return self;
}
-setPieFontSize: (float) size
{
pieFontSize = size;
[self display];
return self;
}
-setPieFont: (char *) fontName
{
strcpy(pieFont, fontName);
[self display];
return self;
}
-normalize; /* make sure that all of the values add up to 360 */
{
int i;
float total=0.0;
for (i=0; i<numWedges; i++) {
total += wedgeValue[i];
}
for(i=0; i<numWedges; i++) {
normData[i] = wedgeValue[i]*360.0/total;
}
[self display]; // we always want to do this, avoid duplicaion
return self;
}
-addPieWedge: (float)value: (char *)inLabel: (float)inGray;
{
wedgeValue[numWedges] = value;
strcpy(labels[numWedges], inLabel);
grays[numWedges] = inGray;
numWedges += 1;
[numWedgesText setIntValue:numWedges];
[self normalize];
return self;
}
-removePieWedge: (int)index;
{
int i;
for (i=index; i<=numWedges-1; i++) {
wedgeValue[i-1] = wedgeValue[i];
strcpy(labels[i-1],labels[i]);
grays[i-1] = grays[i];
}
wedgeValue[i] = 0.0; // not really necessary
numWedges -= 1;
[numWedgesText setIntValue:numWedges];
[self normalize];
return self;
}
-setPieWedge: (int)wedgeNumber: (float)value: (char *)inLabel: (float)inGray;
{
wedgeValue[wedgeNumber] = value;
strcpy(labels[wedgeNumber], inLabel);
grays[wedgeNumber] = inGray;
[self display];
return self;
}
- drawSelf:(NXRect*)r :(int)c
{
int i, c_x, c_y;
float total = 0.0;
c_x = bounds.size.width/2.0 + bounds.origin.x;
c_y = bounds.size.height/2.0 + bounds.origin.y;
[self translate:c_x :c_y];
[fontID set];
PSsetgray(1.0); // for a white background
NXRectFill(&bounds);
PSsetgray(0.0);
for (i=0; i<numWedges; i++)
{
drawSlice(grays[i], pieSize, total, total+normData[i], pieFontSize, labels[i]);
total = total + normData[i];
}
return self;
}